package ar.edu.utn.frba.gdaia.src.domain;

import java.util.HashSet;
import java.util.Set;

public class ConceptoElemental extends Concepto{

	/**
	 * valor: es el dato externo asociado
	 */
	private Object valor;
	
	/**
	 *  Conceptos que abstraen a este concepto
	 * 
	 */
	private Set padres = null;
	
	/**
	 * Conceptos menos abstractos a los cuales el presente concepto abstrae
	 */
	private Set hijos = null;

	/**
	 * canalIngerso: la via de informacion por el cual capto un valor.
	 */
	private Canal canalIngreso;

	public ConceptoElemental(long nroident, Object valor, Canal canalingreso) {
		super(nroident);
		setValor(valor);
		setCanalIngreso(canalingreso);
	}

	public ConceptoElemental(long nroident, Object valor, Canal canalingreso, long popularidad) {
		super(nroident, popularidad);
		setValor(valor);
		setCanalIngreso(canalingreso);
	}

	public Canal getCanalIngreso() {
		return canalIngreso;
	}

	public void setCanalIngreso(Canal canalIngreso) {
		this.canalIngreso = canalIngreso;
	}

	public Object getValor() {
		return valor;
	}

	public void setValor(Object valor) {
		this.valor = valor;
	}

	/**
	 * 
	 */
	public boolean equals(Object otroConcepto) {
		if (!(otroConcepto instanceof ConceptoElemental))
			return false;

		ConceptoElemental otroConceptoElemental = (ConceptoElemental) otroConcepto;
		
		// caso de conceptos abstractos.
		if(valor == null && ((ConceptoElemental) otroConcepto).getValor()== null){
			//compara por hijos. Tiene que tener si o si hijos.
			return (hijos.equals(otroConceptoElemental.getHijos()));			
		}		

		//caso de los dos elementales
		if(valor != null && ((ConceptoElemental) otroConcepto).getValor()!= null)
			return valor.equals(((ConceptoElemental) otroConcepto).getValor());	
			
		return false;
	}	
 
	
	public int hashCode() {
		return valor==null?System.identityHashCode(this):valor.hashCode();
	}

	public String toString() {
		return valor!=null? valor.toString():"- Empty -";
	}
	
	/**
	 * Agrega un concepto que abstrae al presente concepto.
	 * @param c
	 * @return
	 */
	public boolean addPadre(Concepto c){
		if(this.padres == null)
			padres = new HashSet();
		
		return padres.add(c);
	}
	
	/**
	 * Agrega un concepto al cual el presente concepto abstrae.
	 * Se lo utiliza para luego poder bajar en la gerarquia.
	 * @param c
	 * @return
	 */
	public boolean addHijo(Concepto c){
		if(this.hijos == null)
			hijos = new HashSet();
		
		return hijos.add(c);
	}

	public Set getHijos() {
		return hijos;
	}

	public void setHijos(Set hijos) {
		this.hijos = hijos;
	}

	public Set getPadres() {
		return padres;
	}

	public void setPadres(Set padres) {
		this.padres = padres;
	}

	public boolean tienePadres() {
		return padres == null?false:true;		
	}

	/**
	 * 
	 * @return TRUE si es elemental (es decir, si no tiene hijos)
	 */
	public boolean isElemental() {		
		return hijos == null || hijos.isEmpty()? true:false;
	}
	
	
}
//package ar.edu.utn.frba.gdaia.src.domain;
//
//import java.util.HashSet;
//import java.util.Set;
//
//public class ConceptoElemental extends Concepto{
//
//	/**
//	 * valor: es el dato externo asociado
//	 */
//	private Object valor;
//	
//	/**
//	 *  Conceptos que abstraen a este concepto
//	 * 
//	 */
//	private Set padres = null;
//	
//	/**
//	 * Conceptos menos abstractos a los cuales el presente concepto abstrae
//	 */
//	private Set hijos = null;
//
//	/**
//	 * canalIngerso: la via de informacion por el cual capto un valor.
//	 */
//	private CanalIngreso canalIngreso;
//
//	public ConceptoElemental(long nroident, Object valor, CanalIngreso canalingreso) {
//		super(nroident);
//		setValor(valor);
//		setCanalIngreso(canalingreso);
//	}
//
//	public ConceptoElemental(long nroident, Object valor, CanalIngreso canalingreso, long popularidad) {
//		super(nroident, popularidad);
//		setValor(valor);
//		setCanalIngreso(canalingreso);
//	}
//
//	public CanalIngreso getCanalIngreso() {
//		return canalIngreso;
//	}
//
//	public void setCanalIngreso(CanalIngreso canalIngreso) {
//		this.canalIngreso = canalIngreso;
//	}
//
//	public Object getValor() {
//		return valor;
//	}
//
//	public void setValor(Object valor) {
//		this.valor = valor;
//	}
//
//	/**
//	 * 
//	 */
//	public boolean equals(Object otroConcepto) {
//		if (!(otroConcepto instanceof ConceptoElemental))
//			return false;
//
//		ConceptoElemental otroConceptoElemental = (ConceptoElemental) otroConcepto;
//		
//		// caso de conceptos abstractos.
////		if(valor == null && ((ConceptoElemental) otroConcepto).getValor()== null)
/////*			return 	padres != null && 
////					hijos != null && 
////					otroConceptoElemental.getPadres() != null && 
////					otroConceptoElemental.getHijos() != null &&
////					padres.equals(otroConceptoElemental.getPadres()) &&
////					hijos.equals(otroConceptoElemental.getHijos());*/
////			return this.getNroIdent().equals(otroConceptoElemental.getNroIdent());
//		
//
//		//caso de los dos elementales
//		if(valor != null && ((ConceptoElemental) otroConcepto).getValor()!= null)
//			return valor.equals(((ConceptoElemental) otroConcepto).getValor());	
//
//		//ahora vemos los casos abstractos
//		
//		//significa  que los dos conceptos son abstractos y la comparacion es por nroID
//		if(this.getNroIdent()!= -1L && otroConceptoElemental.getNroIdent() != -1L)
//			return (this.getNroIdent()==(otroConceptoElemental.getNroIdent()));
//		
//		//a partir de aca uno u otro tiene el NroID en null	
//		
//		//compara por padres
////		if (padres==null || ((ConceptoElemental) otroConcepto).getPadres()==null)
////				return false;
////				
//		boolean ret = true;
//		if (padres!=null && ((ConceptoElemental) otroConcepto).getPadres()!=null)
//		ret = ret & this.getPadres().equals(((ConceptoElemental) otroConcepto).getPadres());
//		
//		if (padres==null && ((ConceptoElemental) otroConcepto).getPadres()==null)
//			ret = true;
//		else
//			ret = false;
//			
//		//compara por hijos
////		if (hijos==null || ((ConceptoElemental) otroConcepto).getHijos()==null)
////			return false;
////		
//		if (hijos!=null && ((ConceptoElemental) otroConcepto).getHijos()!=null)
//			return this.getHijos().equals(((ConceptoElemental) otroConcepto).getHijos());
//		
//		if (hijos==null && ((ConceptoElemental) otroConcepto).getHijos()==null)
//			ret = true;
//		else
//			ret = false;
//				
//		return ret;
//		
//	}	
//		
//	public int hashCode() {
//		return valor==null?System.identityHashCode(this):valor.hashCode();
//	}
//
//	public String toString() {
//		return valor!=null? valor.toString():"- Empty -";
//	}
//	
//	/**
//	 * Agrega un concepto que abstrae al presente concepto.
//	 * @param c
//	 * @return
//	 */
//	public boolean addPadre(Concepto c){
//		if(this.padres == null)
//			padres = new HashSet();
//		
//		return padres.add(c);
//	}
//	
//	/**
//	 * Agrega un concepto al cual el presente concepto abstrae.
//	 * Se lo utiliza para luego poder bajar en la gerarquia.
//	 * @param c
//	 * @return
//	 */
//	public boolean addHijo(Concepto c){
//		if(this.hijos == null)
//			hijos = new HashSet();
//		
//		return hijos.add(c);
//	}
//
//	public Set getHijos() {
//		return hijos;
//	}
//
//	public void setHijos(Set hijos) {
//		this.hijos = hijos;
//	}
//
//	public Set getPadres() {
//		return padres;
//	}
//
//	public void setPadres(Set padres) {
//		this.padres = padres;
//	}
//
//	public boolean tienePadres() {
//		return padres == null?false:true;		
//	}
//	
//	
//}